self.Module = {
  onRuntimeInitialized: function () {
      onWasmLoaded();
  }
};

self.importScripts("common.js");
self.importScripts("wmwebparser.js")


function Parser() {
  this.logger             = new Logger("Parser");
  this.coreLogLevel       = 2;
  this.tcp                = 0;
  this.accurateSeek       = true;
  this.wasmLoaded         = false;
  this.tmpReqQue          = [];
  this.cacheBuffer        = null;
  this.decodeTimer        = null;
  this.eventInterval      = null;
  this.videoCallback      = null;
  this.audioCallback      = null;
  this.decoderCallback    = null;
  this.requestCallback    = null;
}

Parser.prototype.processReq = function (req) {
  //this.logger.logInfo("processReq " + req.t + ".");
  switch (req.t) {
      case kInitParserReq:
          this.initParser();
          break;
      case kUninitParserReq:
          this.uninitParser();
          break;
      case kFeedDataReq:
          this.sendData(req.d);
          break;
      default:
          this.logger.logError("Unsupport messsage " + req.t);
  }
};

Parser.prototype.cacheReq = function (req) {
  if (req) {
      this.tmpReqQue.push(req);
  }
};



Parser.prototype.initParser = function () {
  var ret = Module._WMWebParser_Init(this.coreLogLevel, this.videoCallback);
                   
  var objData = {
      t: kInitParserRsp,
      e: ret
  };
  this.cacheBuffer = Module._malloc(1920 * 1080);

  self.postMessage(objData);

  // var _this = this;
  // this.eventInterval = setInterval(function () {
  //   _this.doEvent();
  // }, 5)  
};


Parser.prototype.doEvent = function () {
  var ret = Module._WMWebParser_DoEvent();
}



Parser.prototype.uninitParser = function () {
  var ret = Module._WMWebParser_Uninit();
  this.logger.logInfo("Uninit parser return " + ret + ".");
  if (this.cacheBuffer != null) {
      Module._free(this.cacheBuffer);
      this.cacheBuffer = null;
  }

  if (this.eventInterval) {
    clearInterval(this.eventInterval);
    this.eventInterval = null;
  }
};



Parser.prototype.closeParser = function () {
  this.logger.logInfo("closeParser.");

  var ret = Module._WMWebParser_Close();
  this.logger.logInfo("Close ffmpeg decoder return " + ret + ".");


  var objData = {
      t: kCloseParserRsp,
      e: 0
  };
  self.postMessage(objData);
};


Parser.prototype.sendData = function (data) {
  
  var typedArray = new Uint8Array(data);
  Module.HEAPU8.set(typedArray, this.cacheBuffer);
  
  const ret = Module._WMWebParser_SendData(this.cacheBuffer, typedArray.length);
};





Parser.prototype.onWasmLoaded = function () {
  this.logger.logInfo("Parser Wasm loaded.");
  this.wasmLoaded = true;

  this.videoCallback = Module.addFunction(function (buff, size, mediaType, frameType, nDuration, pts) {
    var outArray = Module.HEAPU8.subarray(buff, buff + size);
    var data = new Uint8Array(outArray);


    var objData = {
      t: kVideoFrame,
      data: data,
      media_type: mediaType,
      frame_type: frameType,
      duration: nDuration,
      pts: pts,
    }
    self.postMessage(objData);
  
  }, 'viid');

  // this.audioCallback = Module.addFunction(function (buff, size, timestamp) {
  //     var outArray = Module.HEAPU8.subarray(buff, buff + size);
  //     var data = new Uint8Array(outArray);
  //     var objData = {
  //         t: kAudioFrame,
  //         s: timestamp,
  //         d: data
  //     };
  //     self.postMessage(objData, [objData.d.buffer]);
  // }, 'viid');

  // this.requestCallback = Module.addFunction(function (offset, availble) {
  //     var objData = {
  //         t: kRequestDataEvt,
  //         o: offset,
  //         a: availble
  //     };
  //     self.postMessage(objData);
  // }, 'vii');

  while (this.tmpReqQue.length > 0) {
      var req = this.tmpReqQue.shift();
      this.processReq(req);
  }
};


self.parser = new Parser;


function onWasmLoaded() {
  if (self.parser) {
      self.parser.onWasmLoaded();
  } else {
      console.log("[ER] No decoder!");
  }
}


self.addEventListener('message', (evt) => {
  if (!self.parser) {
      console.log("[ER] Parser not initialized!");
      return;
  }

  // console.log('decoder worker received', evt.data)

  var req = evt.data;
  if (!self.parser.wasmLoaded) {
      self.parser.cacheReq(req);
      self.parser.logger.logInfo("Temp cache req " + req.t + ".");
      return;
  }

  self.parser.processReq(req);


})


